package gameLogic;

public class GameController {
	Board b;
	Observer ob;
	Referee r;
	
	Player p1;
	Player p2;
	
	static int sleepTime = 500;

	public GameController(PlayerType pt1, PlayerType pt2) {
		initNewGame(pt1, pt2);
	}
	
	public void initNewGame(PlayerType pt1, PlayerType pt2) {
		b = new Board();
		ob = new Observer();
		r = new Referee(b,ob);
		
		b.addEventHandler(ob);
		p1 = getPlayerByType(pt1, BoardState.X);
		p2 = getPlayerByType(pt2, BoardState.O);
		System.out.println("New Game initialized. "+pt1+" "+pt2);
	}
	
	Player getPlayerByType(PlayerType pt, BoardState s) {
		if(pt == PlayerType.HUMAN)
			return new PlayerHuman(b, s, ob);
		else if(pt == PlayerType.HUMAN_AIDED) {
			Strategy block = new Strategy3InR(b, s, ob, -1);
			PlayerAI hp = new PlayerAI(b, s, ob);
			hp.addStrategy(block);
			return hp;
		}
		else {
			Strategy rand = new StrategyRandom(b, s, ob);
			Strategy win = new Strategy3InR(b, s, ob, 1);
			Strategy block = new Strategy3InR(b, s, ob, -1);
			Strategy centre = new StrategyCenter(b, s, ob);
			Strategy fork = new StrategyFork(b, s, ob);
			Strategy forkBlocking = new StrategyForkBlock(b, s, ob);
			Strategy corner = new StrategyCorner(b, s, ob);
			
			PlayerAI p = new PlayerAI(b, s, ob);
			p.addStrategy(rand);

			if(pt == PlayerType.AI_BLOCKING)
				p.addStrategy(block);
			else if(pt == PlayerType.AI_SMART) {
				p.addStrategy(block);
				p.addStrategy(win);
			}
			else if(pt == PlayerType.AI_MASTER) {
				p.addStrategy(block);
				p.addStrategy(win);
				p.addStrategy(centre);
				p.addStrategy(fork);
				p.addStrategy(forkBlocking);
				p.addStrategy(corner);
			}
			return p;
		}
	}

	public int startGame() {
		int gameResult = 0;
		
		while ((gameResult = r.judge()) == 0) {
			
			p1.makeMove();
			//sleep();
			
			if ((gameResult = r.judge()) != 0)
				break;

			p2.makeMove();
			//sleep();
		}
		System.out.println("final: " + gameResult);		
		b.print();
		return gameResult;
		//sleep();
	}
	
	public static void sleep() {
		try {
			Thread.sleep(sleepTime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public void addBoardUpdatedEventHandler(EventHandler eh) {
		b.addEventHandler(eh);
	}
	
	public void addGetUserMoveEventHandler(EventHandler eh) {
		p1.addEventHandler(eh);
		p2.addEventHandler(eh);
	}
}
